﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Client;
using System.Web;
using System.Net;
using System.Net.Mail;
using System.Xml;

    public class SPDataLayer
    {
        public ListItemCollection GetListItems(Uri SiteAddress, string ListName)
        {
            CamlQuery CAMLQuery = new CamlQuery ();
            CAMLQuery.ViewXml = "<View/>";
            return GetListItems(SiteAddress, ListName, CAMLQuery);
        }

        public ListItemCollection GetListItems(Uri SiteAddress, string ListName, CamlQuery CAMLQuery)
        {
            // Local variables
            ClientContext clientContext;
            Web site;
            List expectedList;

            try
            {
                clientContext = new ClientContext(SiteAddress);
            }
            catch (Exception)
            {
                EventLogHandler.WriteMessageToLog("Unable to get the client context. Please check ...", System.Diagnostics.EventLogEntryType.Error);
                return null;
            }

            try
            {
                site = clientContext.Web;
            }
            catch (Exception)
            {
                EventLogHandler.WriteMessageToLog("Unable to get the site: " + SiteAddress + " Please check ...", System.Diagnostics.EventLogEntryType.Error);
                return null;
            }

            try
            {
                expectedList = site.Lists.GetByTitle(ListName);
            }
            catch (Exception)
            {
                EventLogHandler.WriteMessageToLog("Unable to get the list: " + SiteAddress + " - " + ListName + " Please check ...", System.Diagnostics.EventLogEntryType.Error);
                return null;
            }

            try
            {
               ListItemCollection listItmes = expectedList.GetItems(CAMLQuery); 
               listItmes = expectedList.GetItems(CAMLQuery);
               clientContext.Load(expectedList);
               clientContext.Load(listItmes);
               clientContext.ExecuteQuery();
               return listItmes;
            }
            catch (Exception ex)
            {
                EventLogHandler.WriteMessageToLog(ex.Message, System.Diagnostics.EventLogEntryType.Error);
                return null;
            }
        }

        public bool SendSMS(string SMSServerIP, string SMSServerPort, string PhoneNumber, string Message)
        {
            try
            {
                UriBuilder urlBuilder = new UriBuilder();

                urlBuilder.Host = SMSServerIP;
                urlBuilder.Port = System.Convert.ToInt32(SMSServerPort);

                urlBuilder.Query = string.Format("PhoneNumber=%2B" + PhoneNumber + "&Text=" + Message);

                WebProxy myProxy = new WebProxy();

                HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(new Uri(urlBuilder.ToString(), false));

                HttpWebResponse httpResponse = (HttpWebResponse)(httpReq.GetResponse());

                EventLogHandler.WriteMessageToLog(httpResponse.StatusDescription);

                if (httpResponse.StatusCode != HttpStatusCode.OK)
                    return false;
            }
            catch (Exception ex)
            {
                EventLogHandler.WriteMessageToLog("Something went wrong while sending SMS to " + PhoneNumber + Environment.NewLine + ex.Message, System.Diagnostics.EventLogEntryType.Warning);
                return false;
            }            

            return true;
        }

        public void SendEmail(string SMTPHostIP, string SMTPHostPort, string FromAddress, string ToAddress, string Subject, string Message)
        {
            /*
             *  message.Fields.Add( "http://schemas.microsoft.com/cdo/configuration/smtpauthenticate",1 );
             *  message.Fields.Add( "http://schemas.microsoft.com/cdo/configuration/sendusername","SmtpHostUserName" );
             *  message.Fields.Add( "http://schemas.microsoft.com/cdo/configuration/sendpassword","SmtpHostPassword" );
             */

            System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage();
            message.To.Add(ToAddress);
            message.Subject = Subject;
            message.From = new System.Net.Mail.MailAddress(FromAddress);
            message.Body = Message;

            // User state could be any object, I am using message as this object so that I can get all the details in the completed function call
            object UserState = message;

            System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient(SMTPHostIP);
            smtp.Port = Convert.ToInt32(SMTPHostPort);
            smtp.UseDefaultCredentials = true;
            smtp.SendCompleted += new System.Net.Mail.SendCompletedEventHandler(smtp_SendCompleted);
            
            smtp.SendAsync(message, UserState);
            EventLogHandler.WriteMessageToLog("Message to be sent is queued for " + message.To + " address.");
        }

        void smtp_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            MailMessage sentMessage = e.UserState as MailMessage;
            EventLogHandler.WriteMessageToLog("Message send completed for " + sentMessage.To + " address.");
        }

        public bool DoesSiteExists (Uri SiteAddress)
        {
            // Local variables
            ClientContext clientContext;
            Web site;

            try
            {
                clientContext = new ClientContext(SiteAddress);
            }
            catch (Exception)
            {
                EventLogHandler.WriteMessageToLog("Unable to get the client context. Please check ...", System.Diagnostics.EventLogEntryType.Error);
                return false;
            }

            try
            {
                site = clientContext.Web;
            }
            catch (Exception)
            {
                EventLogHandler.WriteMessageToLog("Unable to get the site: " + SiteAddress + " Please check ...", System.Diagnostics.EventLogEntryType.Error);
                return false;
            }

            clientContext.Dispose();
            return true;
        }

        public List<List> GetLists(Uri SiteAddress)
        {
            List <List> allLists = new List<List>();
            using (ClientContext ClientContextInstance = new ClientContext (SiteAddress))
            {
                try
                {
                    Web SiteInstance = ClientContextInstance.Web;
                    var listObjects = ClientContextInstance.LoadQuery(SiteInstance.Lists);
                    ClientContextInstance.ExecuteQuery();

                    foreach (List currentList in listObjects)
                    {
                        allLists.Add(currentList);
                    }
                }
                catch (Exception)
                {
                    allLists = null;
                }                
            }

            return allLists;
        }

        public List<Field> GetListColumns(Uri SiteAddress, string ListTitle)
        {
            List expectedListInstance = null;
            List<Field> allFields = new List<Field>();

            using (ClientContext ClientContextInstance = new ClientContext (SiteAddress))
            {
                Web SiteInstance = ClientContextInstance.Web;
                expectedListInstance = SiteInstance.Lists.GetByTitle(ListTitle);
                var fieldObjects = ClientContextInstance.LoadQuery(expectedListInstance.Fields);                
                ClientContextInstance.ExecuteQuery();

                foreach (Field CurrentField in fieldObjects)
                {
                    allFields.Add(CurrentField);
                }
            }

            return allFields;
        }

        public List<Form> GetListForms(Uri SiteAddress, string ListTitle)
        {
            List expectedListInstance = null;
            List<Form> allForms = new List<Form>();

            using (ClientContext ClientContextInstance = new ClientContext(SiteAddress))
            {
                Web SiteInstance = ClientContextInstance.Web;
                expectedListInstance = SiteInstance.Lists.GetByTitle(ListTitle);                
                var formObjects = ClientContextInstance.LoadQuery(expectedListInstance.Forms);
                try
                {
                    ClientContextInstance.ExecuteQuery();
                    foreach (Form CurrentForm in formObjects)
                    {
                        allForms.Add(CurrentForm);
                    }
                }
                catch (Exception)
                {

                }
            }

            return allForms;
        }

        public string GetListSchemaXML(Uri SiteAddress, string ListTitle)
        {
            List expectedListInstance = null;
            string ListSchemXML = string.Empty;

            using (ClientContext ClientContextInstance = new ClientContext(SiteAddress))
            {
                Web SiteInstance = ClientContextInstance.Web;
                expectedListInstance = SiteInstance.Lists.GetByTitle(ListTitle);
                ClientContextInstance.Load(expectedListInstance, eList => eList.SchemaXml);
                try
                {
                    ClientContextInstance.ExecuteQuery();
                    ListSchemXML = expectedListInstance.SchemaXml;
                }
                catch (Exception)
                {

                }
            }

            return ListSchemXML;
        }

        public List CreateList(Uri SiteAddress, string ListTitle, Guid ListTemplateID, string ListSchemaXML)
        {
            List NewlyCreatedList = null;
            XmlDocument ListSchemaXMLInstance = new XmlDocument();

            using (ClientContext ClientContextInstance = new ClientContext(SiteAddress))
            {
                Web SelectedWeb = ClientContextInstance.Web;

                ListCreationInformation newListCreationInformation = new ListCreationInformation();
                
                try
                {
                    ListSchemaXMLInstance.LoadXml(ListSchemaXML);
                    
                    ClientContextInstance.Load (SelectedWeb, sw => sw.ListTemplates);
                    ClientContextInstance.ExecuteQuery();

                    ListTemplateCollection ltc = SelectedWeb.ListTemplates;

                    foreach (ListTemplate currentListTemplate in ltc)
                    {
                        Guid TemplateFeatureID = currentListTemplate.FeatureId;
                    }

                    newListCreationInformation.TemplateFeatureId = ListTemplateID;
                    newListCreationInformation.CustomSchemaXml = ListSchemaXML;

                    ClientContextInstance.Load(SelectedWeb, sw => sw.Lists);
                    ClientContextInstance.ExecuteQuery();

                    newListCreationInformation.Title = ListTitle;
                    newListCreationInformation.TemplateType = (int)ListTemplateType.Links;
                    NewlyCreatedList = SelectedWeb.Lists.Add(newListCreationInformation);
                    ClientContextInstance.ExecuteQuery();
                }
                catch (Exception ex)
                {
                    return null;
                }                
            }

            return NewlyCreatedList;
        }
    }